<?php


/**
 * Notes:
 * PROJECT_NAME : ERP v1.8 重构erp
 * User: 夏鱼儿<397072174@qq.com>
 * Date: 2024/5/10
 * Time: 15:31
 */

namespace app\service;

class RedisLock
{

    //锁的键
    private string  $key;
    //超时时间
    private int $timeout = 1;
    //重试间隔时间:单位毫秒
    private int $retryInterval = 100;

    public function __construct($key) {
        $this->key = $key;
    }

    public function lock(): bool|string
    {
        $startTime = microtime(true);
        $endTime = $startTime + $this->timeout;
        $identifier = uniqid();

        while (microtime(true) < $endTime) {
            if (redis()->set($this->key, $identifier, ['NX', 'EX' => $this->timeout])) {
                return $identifier;
            }
            usleep($this->retryInterval * 1000);
        }
        return false;
    }

    /**
     * 解锁
     * @param $identifier
     * @return mixed
     */
    public function unlock($identifier): mixed
    {
        // Lua脚本
        $script = "
            if redis.call('get', KEYS[1]) == ARGV[1] then
                return redis.call('del', KEYS[1])
            else
                return 0
            end";
        return redis()->eval($script, [$this->key, $identifier], 1);//执行  返回0或1 代表失败/成功
    }
}